# Author Zenos
# Create 2025/2/27 上午10:57
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib
import platform
import numpy as np

# 判断操作系统 设置中文字体
system_name = platform.system()
if system_name == "Darwin":  # macOS
    matplotlib.rcParams['font.sans-serif'] = ['PingFang HK']
elif system_name == "Windows":
    matplotlib.rcParams['font.sans-serif'] = ['SimHei']  # Windows 使用黑体

# matplotlib.use('Agg')  # 这会让 matplotlib 使用非交互模式
# 定义35个显著的颜色，每个类别用一个颜色表示
colors = [
    [0, 0, 0],  # 类别 0  背景 - 黑色
    [255, 0, 0],  # 类别 1  红色
    [0, 255, 0],  # 类别 2  绿色
    [0, 0, 255],  # 类别 3  蓝色
    [255, 255, 0],  # 类别 4  黄色
    [255, 0, 255],  # 类别 5  洋红
    [0, 255, 255],  # 类别 6  青色
    [128, 0, 0],  # 类别 7  深红
    [0, 128, 0],  # 类别 8  深绿
    [0, 0, 128],  # 类别 9  深蓝
    [128, 128, 0],  # 类别 10 橄榄色
    [128, 0, 128],  # 类别 11 紫色
    [0, 128, 128],  # 类别 12 深青色
    [192, 192, 192],  # 类别 13 银色
    [128, 128, 128],  # 类别 14 灰色
    [255, 165, 0],  # 类别 15 橙色
    [0, 100, 0],  # 类别 16 深森林绿
    [139, 0, 0],  # 类别 17 深红色
    [85, 107, 47],  # 类别 18 暗橄榄绿
    [70, 130, 180],  # 类别 19 钢蓝色
    [176, 224, 230],  # 类别 20 浅蓝色
    [255, 105, 180],  # 类别 21 热粉色
    [124, 252, 0],  # 类别 22 草坪绿
    [64, 224, 208],  # 类别 23 浅海蓝色
    [255, 20, 147],  # 类别 24 深粉色
    [218, 165, 32],  # 类别 25 金色
    [72, 61, 139],  # 类别 26 暗蓝色
    [238, 130, 238],  # 类别 27 紫罗兰色
    [250, 128, 114],  # 类别 28 鲑鱼色
    [244, 164, 96],  # 类别 29 棕色
    [0, 191, 255],  # 类别 30 深天蓝色
    [255, 69, 0],  # 类别 31 珊瑚红
    [46, 139, 87],  # 类别 32 海洋绿
    [75, 0, 130],  # 类别 33 靛蓝色
    [210, 105, 30]  # 类别 34 巧克力色
]
# 将颜色转换为 0~1 之间的浮点数，以便 Matplotlib 处理。
colors = np.array(colors) / 255.0
# 定义类别名称字典，每个类别编号对应一个中文名称
classes = {0: '背景', 1: '点', 2: '宝盖点', 3: '斜钩', 4: '横', 5: '横斜钩', 6: '横钩', 7: '横撇', 8: '横撇弯钩',
           9: '横折',
           10: '横折钩', 11: '横折提', 12: '横折折', 13: '横折弯钩', 14: '横折折撇', 15: '横折折折钩', 16: '弯钩',
           17: '捺',
           18: '撇', 19: '撇点', 20: '撇折', 21: '竖', 22: '竖钩', 23: '竖提', 24: '竖弯', 25: '竖弯钩',
           26: '竖折', 27: '竖折撇', 28: '竖折折', 29: '竖折折钩', 30: '提', 31: '卧钩', 32: '走之', 33: '横折折折',
           34: '交叉区'}


def show_image_label(image, label, pred=False):
    # 生成彩色标签图
    color_label = np.zeros((320, 320, 3), dtype=np.float32)
    for i in range(len(colors)):
        color_label[label == i] = colors[i]

    # 获取唯一的类别
    unique_labels = np.unique(label)
    print("标签中包含的类别:", unique_labels)

    # 显示类别名称
    for label_value in unique_labels:
        print(f"类别编号: {label_value}, 名称: {classes.get(label_value, '没有对应的类别名称，请检查classes字典。')}")

    # 创建画布
    fig, ax = plt.subplots(1, 2, figsize=(12, 5))

    # 显示原始灰度图
    ax[0].imshow(image, cmap='binary')
    ax[0].set_title("图像")
    ax[0].axis('off')

    # 显示彩色标签图
    ax[1].imshow(color_label)
    if pred:
        ax[1].set_title("预测")
    else:
        ax[1].set_title("标签")
    ax[1].axis('off')

    # 添加图例，仅显示当前出现的类别
    handles = [mpatches.Patch(color=colors[l], label=classes[l]) for l in unique_labels]
    plt.legend(handles=handles, bbox_to_anchor=(1, 1), loc='upper left', borderaxespad=0.)

    plt.show()


def plot_class_ratios(class_pixel_counts, class_ratios):
    # 绘制条形图
    plt.figure(figsize=(12, 6))

    # 横轴是类别，纵轴是占比
    plt.bar(range(1, 35), class_ratios[1:], color='skyblue')  # 从类别 1 到 34

    # 添加标题和标签
    plt.title('Class Pixel Ratio Distribution', fontsize=16)
    plt.xlabel('Class ID', fontsize=12)  # 横轴标签为 Class ID
    plt.ylabel('Pixel Ratio', fontsize=12)

    # 设置横轴的类别 ID，排除 0 和 35
    plt.xticks(range(1, 35), range(1, 35))  # 只显示类别 1 到 34，删除 rotation=90

    # 显示条形图
    plt.tight_layout()
    plt.show()


def plot_class_ratios(class_pixel_ratios, class_count_ratios):
    # 绘制条形图
    plt.figure(figsize=(12, 6))

    # 设置横轴的类别 ID，排除 0 和 35
    x_ticks = range(1, 35)  # 只显示类别 1 到 34

    # 绘制类别像素占比条形图（蓝色）
    plt.bar(x_ticks, class_pixel_ratios[1:], color='skyblue', width=0.4, label='Pixel Ratio')

    # 绘制类别个数占比条形图（橙色）
    plt.bar([x + 0.4 for x in x_ticks], class_count_ratios[1:], color='orange', width=0.4, label='Class Count Ratio')

    # 添加标题和标签
    plt.title('Class Pixel and Count Ratio Distribution', fontsize=16)
    plt.xlabel('Class ID', fontsize=12)  # 横轴标签为 Class ID
    plt.ylabel('Ratio', fontsize=12)

    # 设置横轴的类别 ID，排除 0
    plt.xticks(x_ticks)  # 只显示类别 1 到 34

    # 添加图例
    plt.legend()

    # 显示条形图
    plt.tight_layout()
    plt.show()

